package com.surfacing.rcp.client.listeners;

import java.util.ArrayList;

import org.apache.log4j.Logger;

import com.surfacing.rcp.client.Activator;
import com.surfacing.rcp.client.modelManager.LoginManager;
import com.surfacing.rcp.client.modelManager.ModelFactory;
import com.surfacing.rcp.client.modelManager.SessionManager;
import com.surfacing.rcp.model.common.AbstractMessage;
import com.surfacing.rcp.model.common.IConnectionStates;
import com.surfacing.rcp.model.entity.Login;
import com.surfacing.rcp.model.entity.Logout;
import com.surfacing.rcp.model.entity.SystemMessage;

public class SessionListener extends ClientListenerAdapter {
	private static final Logger log = Logger.getLogger(SessionListener.class);

	protected SessionManager session = SessionManager.getInstance();
	protected LoginManager manager = ModelFactory.getInstance()
			.getLoginManager();

	@Override
	public void add(AbstractMessage addMessage) {
		if (addMessage instanceof Login) {
			Login addLogin = (Login) addMessage;
			manager.add(addLogin);
		}
	}

	@Override
	public void remove(AbstractMessage removeMessage) {
		if (removeMessage instanceof Login) {
			Login removeLogin = (Login) removeMessage;
			manager.remove(removeLogin);
		}
	}

	@Override
	public void loginMessage(AbstractMessage message) {
		// cast to a login message
		Login login = (Login) message;
		// check the login
		if (login.isLoggedIn()) {
			session.fireLoginSuccessfully(login);
			// log the message
			log.info(Activator.PLUGIN_ID + " - "
					+ "Successfully authenticated " + login.getUsername());
		} else if (login.isIslocked()) {
			session.fireLoginDenied(login);
			log.warn(Activator.PLUGIN_ID + " - "
					+ "User is locked and not allowed to login:"
					+ login.getUsername());
		} else {
			session.fireLoginDenied(login);
			log.warn(Activator.PLUGIN_ID + " - " + "Failed to authenticate "
					+ login.getUsername());
		}
	}

	@Override
	public void logoutMessage(AbstractMessage message) {
		// get the result and cast
		final Logout logout = (Logout) message;
		// check if the user is logged out
		if (logout.isLoggedOut()) {
			session.fireLogout();
			log.info(Activator.PLUGIN_ID + " - "
					+ "Successfully logged out the user: "
					+ logout.getUsername());
		}
	}

	@Override
	public void connectionChange(int status) {
		if (status == IConnectionStates.STATE_DISCONNECTED)
			session.fireConnectionLost();
	}

	@Override
	public void transferFailed(String contentType, String queryType,
			AbstractMessage message) {
		session.fireTransferFailed(contentType, queryType, message);
	}

	@Override
	public void systemMessage(AbstractMessage message) {
		SystemMessage sysMessage = (SystemMessage) message;
		// the log message

		if (sysMessage.getType() == SystemMessage.TYPE_INFO)
			log.info(Activator.PLUGIN_ID + " - " + sysMessage.getMessage());
		else if (sysMessage.getType() == SystemMessage.TYPE_ERROR)
			log.error(Activator.PLUGIN_ID + " - " + sysMessage.getMessage());
		// log as an error message
		else
			log.error(Activator.PLUGIN_ID + " - " + sysMessage.getMessage());
		// log the message
	}

	@Override
	public void update(AbstractMessage updateMessage) {
		// do we have a login message?
		if (updateMessage instanceof Login) {
			Login login = (Login) updateMessage;
			manager.update(login);
		}
	}

	@Override
	public void list(ArrayList<AbstractMessage> listMessage) {
		// get the first item to check the type
		AbstractMessage listObject = listMessage.get(0);
		if (listObject instanceof Login) {
			manager.removeAllEntries();
			// loop and add all logins
			for (AbstractMessage abstractObject : listMessage) {
				Login login = (Login) abstractObject;
				manager.add(login);
			}
		}
	}
}
